package com.young.fragments.demo.activity_result_launcher_demo.fm

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import androidx.core.app.ActivityCompat
import com.young.fragments.databinding.ActivityActivityResultLauncherBinding
import com.young.fragments.demo.activity_result_launcher_demo.ActivityResultLauncherActivity
import com.young.fragments.demo.activity_result_launcher_demo.ResultDoBackActivity
import com.young.lib_fragments.fms.BaseLazyFragment

/**
 * @author huangzehui
 * @date 2025/1/26 23:06 周日
 * @description （fragment）registerForActivityResult 的使用例子，就是 startActivityForResult 的代替
 */
class ActivityResultLauncherFragment : BaseLazyFragment() {

    private lateinit var mBinding: ActivityActivityResultLauncherBinding


    // ResultDoBackActivity 启动器
    private lateinit var mResultDoBackAcLauncher: ActivityResultLauncher<Intent>

    // 单个权限请求启动器
    private lateinit var mSinglePermissionLauncher: ActivityResultLauncher<String>

    //  多个权限请求启动器
    private lateinit var mMultiplePermissionLauncher: ActivityResultLauncher<Array<String>>

    // 悬浮窗权限请求 启动器
    private lateinit var mDrawOverlaysAcLauncher: ActivityResultLauncher<Intent>

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mBinding = ActivityActivityResultLauncherBinding.inflate(inflater, container, false)
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        showBackResult("")
        showRequestResult("")
        initResultLauncher()
        initClick()
    }

    /**
     * 初始化启动结果启动器
     */
    private fun initResultLauncher() {
        mResultDoBackAcLauncher = registerForActivityResultUtil.createActivityResultLauncher(
            this,
            object : ActivityResultCallback<ActivityResult> {

                override fun onActivityResult(result: ActivityResult) {
                    /**
                     * 通过结果码不同，可以共用这个回调用，例如：
                     *             val intent =
                     *                 Intent(this@ActivityResultLauncherActivity, ResultDoBackActivity::class.java)
                     *             // 这里传递给目标页面，目标页面再使用这个设置结果码，之后就可以通过结果码不同，共用一个回调
                     *             intent.putExtra(KEY_RESULT_CODE, RESULT_CODE)
                     *             mResultDoBackAcLauncher.launch(intent)
                     */
                    if (result.resultCode == ActivityResultLauncherActivity.RESULT_CODE) {
                        val text = result.data?.getStringExtra(ResultDoBackActivity.KEY_BACK_DATA)
                        showBackResult(text)
                    }
                }

            })

        mSinglePermissionLauncher = registerForActivityResultUtil.createSinglePermissionLauncher(
            this,
            object : ActivityResultCallback<Boolean> {

                override fun onActivityResult(isGranted: Boolean) {
                    val str = StringBuilder()
                    if (isGranted) {
                        str.append("单个权限：已授权成功")
                    } else {
                        str.append("单个权限：授权失败")
                    }
                    showRequestResult(str.toString())
                }

            })


        mMultiplePermissionLauncher =
            registerForActivityResultUtil.createMultiplePermissionLauncher(
                this,
                object : ActivityResultCallback<Map<String, Boolean>> {

                    override fun onActivityResult(result: Map<String, Boolean>) {
                        val str = StringBuilder()
                        str.append("多个权限请求：\n")
                        for (entry in result) {
                            str.append("${entry.key} = ${entry.value}").append("\n")
                        }

                        showRequestResult(str.toString())
                    }

                })

        mDrawOverlaysAcLauncher = registerForActivityResultUtil.createActivityResultLauncher(
            this,
            object : ActivityResultCallback<ActivityResult> {

                override fun onActivityResult(result: ActivityResult) {
                    if (result.resultCode == Activity.RESULT_CANCELED) {
                        // 从设置页回来，无论有没有授权，都会返回 Activity.RESULT_CANCELED
                        // 所以我们这里自己判断是否有授权
                        if (canDrawOverlays()) {
                            Toast.makeText(
                                requireContext(),
                                "(fragment)悬浮窗，授权成功",
                                Toast.LENGTH_LONG
                            ).show()
                        } else {
                            Toast.makeText(
                                requireContext(),
                                "(fragment)悬浮窗，授权失败",
                                Toast.LENGTH_LONG
                            ).show()
                        }
                    }
                }

            })
    }

    private fun initClick() {
        val clickListener = View.OnClickListener {
            when (it) {
                mBinding.btnJump -> {
                    val intent =
                        Intent(
                            requireContext(),
                            ResultDoBackActivity::class.java
                        )
                    // 这里传递给目标页面，目标页面再使用这个设置结果码，之后就可以通过结果码不同，共用一个回调
                    intent.putExtra(
                        ActivityResultLauncherActivity.KEY_RESULT_CODE,
                        ActivityResultLauncherActivity.RESULT_CODE
                    )
                    mResultDoBackAcLauncher.launch(intent)
                }

                mBinding.btnRequestSinglePermission -> {
                    val permission = Manifest.permission.CAMERA

                    if (ActivityCompat.shouldShowRequestPermissionRationale(
                            requireActivity(),
                            permission
                        )
                    ) {
                        // 已拒绝过一次，就会触发这个，正常来说这次是来补充说明的，
                        // 然后这个展示后的请求，再次拒绝，则之后的每次拒绝都是可以弹自定义弹出框的
                        showRequestResult("单个权限已被拒绝，补充一个说明弹出框，再次请求")
                    } else {
                        registerForActivityResultUtil.requestSinglePermission(
                            mSinglePermissionLauncher,
                            permission
                        )
                    }
                }

                mBinding.btnRequestMultiplePermission -> {
                    val permissions = arrayOf(
                        Manifest.permission.CALL_PHONE,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                    )

                    val str = StringBuilder()
                    str.append("多个权限请求：\n")

                    var isTriggerShould = false

                    for (permission in permissions) {
                        if (ActivityCompat.shouldShowRequestPermissionRationale(
                                requireActivity(),
                                permission
                            )
                        ) {
                            isTriggerShould = true
                            str.append("${permission} 权限已被拒绝，补充一个说明弹出框，再次请求\n")
                        } else {
                            if (ActivityCompat.checkSelfPermission(requireContext(), permission) == PackageManager.PERMISSION_GRANTED){
                                str.append("${permission} 已授权\n")
                            } else {
                                str.append("${permission} 可进行请求，不过整体还是先处理了 shouldShowRequestPermissionRationale 才可以请求\n")
                            }
                        }
                    }

                    if (isTriggerShould){
                        showRequestResult(str.toString())
                    } else {
                        registerForActivityResultUtil.requestMultiplePermission(
                            mMultiplePermissionLauncher,
                            *permissions
                        )
                    }



                }


                mBinding.btnGoFloatSetting -> {
                    if (canDrawOverlays()) {
                        Toast.makeText(
                            requireContext(),
                            "(fragment)已有悬浮窗权限",
                            Toast.LENGTH_LONG
                        ).show()
                    } else {
                        goFloatSetting()
                    }
                }

            }
        }

        mBinding.btnJump.setOnClickListener(clickListener)
        mBinding.btnRequestSinglePermission.setOnClickListener(clickListener)
        mBinding.btnRequestMultiplePermission.setOnClickListener(clickListener)
        mBinding.btnGoFloatSetting.setOnClickListener(clickListener)

    }

    /**
     * 展示返回结果
     *
     * @param info 返回结果信息
     */
    private fun showBackResult(info: String?) {
        mBinding.tvInfo.text = "返回结果(fragment)：${info}"
    }


    /**
     * 展示请求权限返回结果
     *
     * @param info 返回结果信息
     */
    private fun showRequestResult(info: String?) {
        mBinding.tvPermissionInfo.text = "权限请求结果(fragment)：${info}"
    }

    /**
     * 跳转悬浮窗设置页
     */
    private fun goFloatSetting() {
        val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
        intent.setData(Uri.parse("package:${requireContext().packageName}"))

        mDrawOverlaysAcLauncher.launch(intent)
    }

    /**
     * 是否有悬浮窗权限
     */
    private fun canDrawOverlays(): Boolean {
        // 在Activity或Fragment中请求权限
        return !(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(requireContext()))
    }
}